package com.sxhuayuan.parking.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Calendar;
import java.util.Date;

import org.apache.commons.lang.StringUtils;

public class DateUtils {

	/**
	 * 输入 第几个月后的天数 时分秒为0
	 * 
	 * @throws ParseException
	 */
	public static String ConversionTimeStringYesterday(Integer num) {
		Date date = new Date();
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.MONTH, num);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MINUTE, 0);
		date = calendar.getTime();
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String string = dateFormat.format(date);
		return string;
	}

	public static final String DEFAULT_PATTERN = "yyyy-MM-dd HH:mm:ss";
	public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";

	/**
	 * @Description: 当前时间
	 * @return Date
	 */
	public static Date getTime() {
		return Calendar.getInstance().getTime();
	}

	/**
	 * @Description: 当前月第一天0点0分0秒
	 * @return Date
	 */
	public static Date getStartTimeOfCurrentMonth() {
		Calendar cal = Calendar.getInstance();
		return getStartTimeOfMonth(cal.getTime());
	}

	/**
	 * @Description: 当前月第一天0点0分0秒
	 * @return Date
	 */
	public static Date getStartTimeOfMonth(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.DAY_OF_MONTH, 1);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		return cal.getTime();
	}

	/**
	 * @Description: 当前月第一天0点0分0秒
	 * @return Date
	 */
	public static Date getEndTimeOfMonth(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.DAY_OF_MONTH, cal.getMaximum(Calendar.DAY_OF_MONTH));
		cal.set(Calendar.HOUR_OF_DAY, 23);
		cal.set(Calendar.MINUTE, 59);
		cal.set(Calendar.SECOND, 59);
		return cal.getTime();
	}

	/**
	 * @Description: 当前月第一天0点0分0秒
	 * @return Date
	 */
	public static Date getEndTimeOfCurrentMonth() {
		Calendar cal = Calendar.getInstance();
		return getEndTimeOfMonth(cal.getTime());
	}

	/**
	 * 今天0点0分0秒
	 * 
	 * @return
	 */
	public static Date getStartTimeOfToday() {
		return getStartTimeOfOneday(0);
	}

	/**
	 * 获取相对于今天前几天或后几天
	 * 
	 * @param num
	 * @return
	 */
	public static Date getStartTimeOfOneday(int num) {
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.DAY_OF_YEAR, cal.get(Calendar.DAY_OF_YEAR) + num);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		return cal.getTime();
	}

	/**
	 * 今天23点23分50秒
	 * 
	 * @return
	 */
	public static Date getEndTimeOfToday() {
		return getEndTimeOfOneday(0);
	}

	/**
	 * 某天23点23分59秒
	 * 
	 * @return
	 */
	public static Date getEndTimeOfOneday(int num) {
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.DAY_OF_YEAR, cal.get(Calendar.DAY_OF_YEAR) + num);
		cal.set(Calendar.HOUR_OF_DAY, 23);
		cal.set(Calendar.MINUTE, 59);
		cal.set(Calendar.SECOND, 59);
		return cal.getTime();
	}

	/**
	 * 某天0点0分0秒
	 * 
	 * @return
	 */
	public static Date getStartTimeOfDate(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		return cal.getTime();
	}

	/**
	 * 今天23点23分50秒
	 * 
	 * @return
	 */
	public static Date getEndTimeOfDate(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.HOUR_OF_DAY, cal.getActualMaximum(Calendar.HOUR_OF_DAY));
		cal.set(Calendar.MINUTE, cal.getActualMaximum(Calendar.MINUTE));
		cal.set(Calendar.SECOND, cal.getActualMaximum(Calendar.SECOND));
		return cal.getTime();
	}

	public static String format() {
		return format(Calendar.getInstance().getTime());
	}

	/**
	 * 格式化时间 yyyy-MM-dd HH:mm
	 * 
	 * @param date
	 * @return
	 */
	public static String format(Date date) {
		return format(date, DEFAULT_PATTERN);
	}

	/**
	 * 格式化时间 yyyy-MM-dd HH:mm
	 * 
	 * @param pattern
	 * @return
	 */
	public static String format(String pattern) {
		if (pattern == null || "".equals(pattern)) {
			return "";
		}
		return format(Calendar.getInstance().getTime(), pattern);
	}

	/**
	 * 格式化时间 yyyy-MM-dd HH:mm
	 * 
	 * @param date
	 * @return
	 */
	public static String format(Date date, String pattern) {
		if (date == null)
			return null;
		if (StringUtils.isEmpty(pattern)) {
			throw new RuntimeException("date or pattern is null");
		}
		SimpleDateFormat format = new SimpleDateFormat(pattern);
		return format.format(date);
	}

	public static boolean isToday(Date date) {
		Calendar cal = Calendar.getInstance();
		int year = cal.get(Calendar.YEAR);
		int day = cal.get(Calendar.DAY_OF_YEAR);
		cal.setTime(date);
		int year2 = cal.get(Calendar.YEAR);
		int day2 = cal.get(Calendar.DAY_OF_YEAR);
		return year == year2 && day == day2;
	}

	/**
	 * 使用预设格式提取字符串日期
	 * 
	 * @param strDate
	 *            日期字符串
	 * @return
	 */
	public static Date parse(String strDate) {
		return parse(strDate, DEFAULT_PATTERN);
	}

	/**
	 * 使用用户格式提取字符串日期
	 * 
	 * @param strDate
	 *            日期字符串
	 * @param pattern
	 *            日期格式
	 * @return
	 */
	public static Date parse(String strDate, String pattern) {
		if (strDate == null || "".equals(strDate))
			return null;
		SimpleDateFormat df = new SimpleDateFormat(pattern);
		try {
			return df.parse(strDate);
		} catch (ParseException e) {
			e.printStackTrace();
			return null;
		}
	}

	public static Date add(Date date, int calendarField, int amount) {
		if (date == null) {
			throw new IllegalArgumentException("The date must not be null");
		}
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.add(calendarField, amount);
		return c.getTime();
	}

	public static Date addDays(Date date, int amount) {
		return add(date, Calendar.DAY_OF_MONTH, amount);
	}

	/**
	 * 获取时间差，YEAR/MONTH/DATE/HOUR/MINUTE/SECOND/MILLISECOND
	 * 
	 * @param start
	 * @param end
	 * @param field
	 * @return
	 * @throws Exception
	 */
	public static long diff(Date start, Date end, int field) {
		Calendar sc = Calendar.getInstance();
		sc.setTime(start);
		Calendar ec = Calendar.getInstance();
		ec.setTime(end);
		switch (field) {
		case Calendar.YEAR:
			return ec.get(field) - sc.get(field);
		case Calendar.MONTH:
			return (ec.get(Calendar.YEAR) - sc.get(Calendar.YEAR)) * 12 + (ec.get(field) - sc.get(field));
		case Calendar.DAY_OF_YEAR:
			return (end.getTime() - start.getTime()) / (24 * 60 * 60 * 1000);
		case Calendar.DATE:
			return (end.getTime() - start.getTime()) / (24 * 60 * 60 * 1000);
		case Calendar.HOUR:
			return (end.getTime() - start.getTime()) / (60 * 60 * 1000);
		case Calendar.MINUTE:
			return (end.getTime() - start.getTime()) / (60 * 1000);
		case Calendar.SECOND:
			return (end.getTime() - start.getTime()) / 1000;
		case Calendar.MILLISECOND:
			return (end.getTime() - start.getTime());
		default:
			return -1;
		}
	}

	/**
	 * 获取日期差
	 * 
	 * @param start
	 * @param end
	 * @return
	 */
	public static long diff(LocalDate start, LocalDate end) {
		return end.getDayOfYear() - start.getDayOfYear();

	}

	/**
	 * 分钟转为天-时-分 显示
	 * 
	 * @param minutes
	 * @return
	 */
	public static String formatParkTime(Long minutes) {
		if (minutes == null || minutes <= 0)
			return "0分";
		StringBuilder s = new StringBuilder();
		Integer onedayMinutes = 60 * 24;
		if (minutes >= onedayMinutes)
			s.append(minutes / onedayMinutes).append("天");
		if (minutes >= 60)
			s.append((minutes % onedayMinutes) / 60).append("时");
		s.append(minutes % 60).append("分");
		return s.toString();
	}

	/**
	 * 现在到晚上23:59:59还剩多少秒
	 * 
	 * @return
	 */
	public static long nowToTomorrowSecond() {
		return (getEndTimeOfToday().getTime() - new Date().getTime()) / 1000;
	}

	/**
	 * 获取当前 LocalDate 月份的第一天
	 */
	public static LocalDate getMinDate(LocalDate localDate) {
		return LocalDate.of(localDate.getYear(), localDate.getMonthValue(), 1);
	}

	/**
	 * 获取当前 LocalDate 月份的最后一天
	 */
	public static LocalDate getMaxDate(LocalDate localDate) {
		LocalDate minDate = getMinDate(localDate);
		return minDate.plusMonths(1).minusDays(1);
	}

	public static String getStartTimeOfDate(LocalDate date) {
		return date.toString();
	}

	public static Date getStartOfLocalDate(LocalDate localDate) {
		ZoneId zone = ZoneId.systemDefault();
		Instant instant = localDate.atStartOfDay().atZone(zone).toInstant();
		java.util.Date date = Date.from(instant);
		return date;
	}

	public static Date getEndOfLocalDate(LocalDate localDate) {
		ZoneId zone = ZoneId.systemDefault();
		Instant instant = localDate.atTime(23, 59, 59, 999).atZone(zone).toInstant();
		java.util.Date date = Date.from(instant);
		return date;
	}

	public static void main(String[] args) {
		// System.out.println(diff(parse("2018-11-20 9:00:00"), parse("2019-11-20
		// 9:00:00"), Calendar.YEAR));
		// System.out.println(diff(parse("2018-11-20 9:00:00"), parse("2019-11-20
		// 9:00:00"), Calendar.MONTH));
		// System.out.println(diff(parse("2018-11-20 9:00:00"), parse("2019-11-20
		// 9:00:00"), Calendar.DATE));
		// System.out.println(diff(parse("2018-11-20 9:00:00"), parse("2018-11-21
		// 9:00:00"), Calendar.HOUR));
		// System.out.println(diff(parse("2018-11-20 9:00:00"), parse("2018-11-21
		// 9:00:00"), Calendar.MINUTE));
		System.out.println(diff(parse("2018-11-20 9:00:00"), parse("2018-11-20 9:01:01"), Calendar.SECOND));
		//
		// System.out.println(getStartTimeOfToday());
		// System.out.println(getEndTimeOfToday());
		// System.out.println(getStartTimeOfOneday(-1));
		// System.out.println(formatParkTime(60L));
		// System.out.println(formatParkTime(1260L));
		// System.out.println(formatParkTime(60L * 5 + 62));

		// Date date = parse("2019-05-09 12:23:32");
		// System.out.println(diff(date, new Date(), Calendar.DAY_OF_YEAR));
		//
		// System.out.println(getStartTimeOfDate(LocalDate.now()));
		//
		// LocalDate e = LocalDate.now();
		// LocalDate s = e.plusDays(-1);
		// System.out.println(s.toString() + ", " + e.toString());
		// System.out.println(diff(s, e));
	}
}
